package com.b511.swpu.cementbackend.service.impl;

import com.b511.swpu.cementbackend.dao.DataAnalyzeDao;
import com.b511.swpu.cementbackend.dto.input.DataAnalysisInputDto;
import com.b511.swpu.cementbackend.dto.input.dataAnalyze.ConsumptionInputDto;
import com.b511.swpu.cementbackend.dto.input.dataAnalyze.WorkWellCountInputDto;
import com.b511.swpu.cementbackend.dto.output.dataAnalyze.*;
import com.b511.swpu.cementbackend.entity.BA_Well;
import com.b511.swpu.cementbackend.entity.CM_WK_AdditiveConsume;
import com.b511.swpu.cementbackend.entity.CM_WK_BASIC;
import com.b511.swpu.cementbackend.repository.*;
import com.b511.swpu.cementbackend.service.DataAnalysisService;
import com.b511.swpu.cementbackend.util.CollectionUtils;
import com.b511.swpu.cementbackend.util.R;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import com.b511.swpu.cementbackend.util.*;

@Service
public class DataAnalysisServiceImpl implements DataAnalysisService {
    private final SYSM_DataDictRepository sysm_dataDictRepository;

    private final CM_WorkBasicRepository cm_workBasicRepository;

    private final SYSM_CompanyRepository sysm_companyRepository;

    private final DataAnalysisRepository dataAnalysisRepository;

    private final DataAnalyzeDao dataAnalyzeDao;

    public DataAnalysisServiceImpl(SYSM_DataDictRepository sysm_dataDictRepository, CM_WorkBasicRepository cm_workBasicRepository,
                                   SYSM_CompanyRepository sysm_companyRepository, DataAnalysisRepository dataAnalysisRepository,
                                   DataAnalyzeDao dataAnalyzeDao,CM_WK_AdditiveConsumeRepository additiveConsumeRepository) {
        this.sysm_dataDictRepository = sysm_dataDictRepository;
        this.cm_workBasicRepository = cm_workBasicRepository;
        this.sysm_companyRepository = sysm_companyRepository;
        this.dataAnalysisRepository = dataAnalysisRepository;
        this.dataAnalyzeDao = dataAnalyzeDao;
    }


    @Override
    public R getDataByCompanyAndTime(String cementCompany,String work_date,String report_date){
        System.out.println(work_date);
        //设置下面report_date和work_date的时间是为了减少repository的代码
        if ((!"".equals(work_date))&&("".equals(report_date))){
            report_date="3000-01-01";
        }
        else if (("".equals(work_date))&&(!"".equals(report_date))){
            work_date="1000-01-01";
        }
        else if (("".equals(work_date))&&("".equals(report_date))){
            report_date="3000-01-01";
            work_date="1000-01-01";
        }

        //如果cementCompany等于空字符串，那么选择没有作业公司的查询
        if("".equals(cementCompany)){
            //根据井型来查询作业量
            List<Integer> wellTypeCount= new LinkedList<>();
            List<String> wellTypes=sysm_dataDictRepository.findWellType();
            for(String wellType:wellTypes){
                wellTypeCount.add(cm_workBasicRepository.getCountByWellType(wellType,work_date,report_date));
            }
            //根据井别来查询作业量
            List<Integer> wellSpacingCount= new LinkedList<>();
            List<String>  wellSpacings=sysm_dataDictRepository.findWellSpacing();
            for(String wellSpacing:wellSpacings){
                wellSpacingCount.add(cm_workBasicRepository.getCountByWellSpacing(wellSpacing,work_date,report_date));
            }
            //根据套管来查询作用量
            List<Integer> caseSizeCount= new LinkedList<>();
            List<String>  caseSizes=cm_workBasicRepository.getCase_size();
            for(String caseSize:caseSizes){
                caseSizeCount.add(cm_workBasicRepository.getCountByCaseSize(caseSize,work_date,report_date));
            }
            return R.ok().put("wellType",wellTypes)
                    .put("wellSpacing",wellSpacings)
                    .put("caseSize",caseSizes)
                    .put("wellTypeCount",wellTypeCount)
                    .put("wellSpacingCount",wellSpacingCount)
                    .put("caseSizeCount",caseSizeCount);
        }else {
            //根据井型来查询作业量
            List<Integer> wellTypeCount= new LinkedList<>();
            List<String> wellTypes=sysm_dataDictRepository.findWellType();
            for(String wellType:wellTypes){
                wellTypeCount.add(cm_workBasicRepository.getCountByCompanyAndWellType(cementCompany,wellType,work_date,report_date));
            }
            //根据井别来查询作业量
            List<Integer> wellSpacingCount= new LinkedList<>();
            List<String>  wellSpacings=sysm_dataDictRepository.findWellSpacing();
            for(String wellSpacing:wellSpacings){
                wellSpacingCount.add(cm_workBasicRepository.getCountByCompanyAndWellSpacing(cementCompany,wellSpacing,work_date,report_date));
            }
            //根据套管来查询作用量
            List<Integer> caseSizeCount= new LinkedList<>();
            List<String>  caseSizes=cm_workBasicRepository.getCase_size();
            for(String caseSize:caseSizes){
                caseSizeCount.add(cm_workBasicRepository.getCountByCompanyAndCaseSize(cementCompany,caseSize,work_date,report_date));
            }
            return R.ok().put("wellType",wellTypes)
                    .put("wellSpacing",wellSpacings)
                    .put("caseSize",caseSizes)
                    .put("wellTypeCount",wellTypeCount)
                    .put("wellSpacingCount",wellSpacingCount)
                    .put("caseSizeCount",caseSizeCount);
        }

    }

    // 2021.3.18 数据分析 相关功能添加：材料/附件消耗 & 作业井统计
    // 实现 区域、区块、油田 的关联查询

    // 1. 查询全部的 作业公司
    @Override
    public R getCementCompany(){
        return R.ok().putData(dataAnalysisRepository.findCompany());
    }

    // 2. 查询当前作业公司 下的全部 区域
    @Override
    public R getAreaByCompany(String cementCompany){
        return R.ok().putData(dataAnalysisRepository.findArea(cementCompany));
    }

    // 3. 查询当前 作业公司 & 区块 下的全部 区块
    @Override
    public R getBlockByArea(String cementCompany, String area){
        return R.ok().putData(dataAnalysisRepository.findBlock(cementCompany, area));
    }

    // 4. 查询当前 作业公司 & 区域 & 区块 下的全部油田
    // input: area，block
    // output: List<oilfield>
    @Override
    public R getOilfiledByAreaAndBlock(String cementCompany, String area, String block){
        return  R.ok().putData(dataAnalysisRepository.findOilField(cementCompany, area, block));
    }

    // 5. 材料/附件消耗 统计查询接口
    @Override
    public R getMaterialConsumptionByCondition(ConsumptionInputDto consumptionInputDto){

        // 封装返回的数据 DataAnalyzeOutputDto
        DataAnalyzeOutputDto dataAnalyzeOutputDto = new DataAnalyzeOutputDto();

        // 使用分页查询
        // List<WellInfo> wellInfoList = dataAnalyzeDao.queryWellByConditionPageable(consumptionInputDto);

        // add to OutputDto
        List<WellInfo> wellInfoList = dataAnalyzeDao.queryWellByCondition(consumptionInputDto);
        dataAnalyzeOutputDto.setWellInfo(wellInfoList);
        // 符合条件的记录总数
        int total = wellInfoList.size();

        // 查询中涉及的不重复 wellName
        Set<String> wellNameSet = new HashSet<>();
        for(WellInfo tmpInfo : wellInfoList){
            wellNameSet.add(tmpInfo.getWellName());
        }

        // wellNameSet() 大小不能超过 1000：Oracle 限定了 Select in 的使用
        // ORA-01795: 列表中的最大表达式数为 1000
        // 解决方法：<!-- select in 超过1000条数据的解决方法: https://smilenicky.blog.csdn.net/article/details/87922878 -->
        // 上面的博客中，代码有错，已经改好了：util.CollectionUtils
        List<Collection<String>> configSeqs = CollectionUtils.splitCollection(wellNameSet, 1000);

        // wellName in List and group by additiveName sum(amount)
        List<MaterialConsumption> materialConsumption = dataAnalyzeDao.queryMaterialConsumption(configSeqs);
        dataAnalyzeOutputDto.setMaterialConsumption(materialConsumption);

        // wellName in List and group by accessoryName sum(amount)
        List<AccessoryConsumption> accessoryConsumption = dataAnalyzeDao.queryAccessoryConsumption(configSeqs);
        dataAnalyzeOutputDto.setAccessoryConsumption(accessoryConsumption);

        return R.ok().putData(dataAnalyzeOutputDto);
    }

    // 6. 作业井查询统计 接口
    @Override
    public R getWorkWellInfoByCondition(WorkWellCountInputDto workWellCountInputDto){
        // 由 pageNum, pageSize 计算出 startSeq 以及 endSeq
        Integer pageNum = workWellCountInputDto.getPageNum();
        Integer pageSize = workWellCountInputDto.getPageSize();

        // Oracle 分页
        workWellCountInputDto.setStartSeq( (pageNum-1) * pageSize + 1);
        workWellCountInputDto.setEndSeq( pageNum*pageSize );

        // 符合条件的记录总数
        int total = dataAnalyzeDao.queryWorkWellCount(workWellCountInputDto);

        // 只统计井数（不包括领浆，套管尺寸等）
        int wellCount = dataAnalyzeDao.wellCount(workWellCountInputDto) ;

        // 返回结果封装
        WellCountOutputDto wellCountOutputDto = new WellCountOutputDto();
        wellCountOutputDto.setPageNum(pageNum);
        wellCountOutputDto.setPageSize(pageSize);
        wellCountOutputDto.setTotalNum(total);
        wellCountOutputDto.setWellNum(wellCount);
        wellCountOutputDto.setWorkWell(dataAnalyzeDao.queryWorkWell(workWellCountInputDto));

        return R.ok().putData(wellCountOutputDto);
    }

}
